package com.yida.gwj.basis.service.impl;

import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.service.RemoteGwjConfigService;
import com.yida.gwj.basis.domain.GwjInitBusiness;
import com.yida.gwj.basis.domain.GwjInitBusinessBuild;
import com.yida.gwj.basis.domain.GwjInitBusinessLog;
import com.yida.gwj.basis.domain.dto.GwjInitBusinessFlowDTO;
import com.yida.gwj.basis.mapper.GwjInitBusinessMapper;
import com.yida.gwj.basis.service.*;
import com.yida.gwj.common.domain.GwjBaseBusinessBuild;
import com.yida.gwj.common.domain.dto.GwjUserDTO;
import com.yida.gwj.common.enums.GwjBusinessStatus;
import com.yida.gwj.common.utils.GwjConvertUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务（基础数据管理模块）Service业务层处理
 *
 * @author lqq
 * @date 2022-11-15
 */
@Service
public class GwjInitBusinessServiceImpl implements IGwjInitBusinessService {

    @Resource
    private GwjInitBusinessMapper businessMapper;

    @Resource
    private IGwjInitBusinessLogService logService;

    @Resource
    private IGwjInitBusinessBuildService businessBuildService;

    @Resource
    private IGwjInitBusinessCommunityService businessCommunityService;

    @Resource
    private IGwjInitBusinessHouseService businessHouseService;

    @Resource
    private IGwjInitBusinessOwnerService businessOwnerService;

    @Resource
    private RemoteGwjConfigService remoteGwjConfigService;

    /**
     * 新增业务（基础数据管理模块）
     *
     * @param gwjInitBusiness 业务（基础数据管理模块）
     * @return 结果
     */
    @Override
    public int insert(GwjInitBusiness gwjInitBusiness) {
        gwjInitBusiness.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        gwjInitBusiness.setCreateTime(DateUtils.getNowDate());
        return businessMapper.insert(gwjInitBusiness);
    }

    /**
     * 修改业务（基础数据管理模块）
     *
     * @param gwjInitBusiness 业务（基础数据管理模块）
     * @return 结果
     */
    @Override
    public int updateById(GwjInitBusiness gwjInitBusiness) {
        gwjInitBusiness.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        gwjInitBusiness.setUpdateTime(DateUtils.getNowDate());
        System.out.println(gwjInitBusiness.toString());
        return businessMapper.updateById(gwjInitBusiness);
    }

    /**
     * 查询基础数据（业务）列表
     *
     * @param business 基础数据请求参数（业务）
     * @return 基础数据（业务）集合
     */
    @Override
    public List<GwjInitBusiness> getList(GwjInitBusiness business) {
        return businessMapper.selectList(business);
    }

    /**
     * 查询基础数据（业务）
     *
     * @param bizId 业务ID
     * @return /
     */
    @Override
    public GwjInitBusiness getById(Long bizId) {
        return businessMapper.selectById(bizId);
    }

    /**
     * 送件
     *
     * @param businessLog 意见请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void send(GwjInitBusinessLog businessLog) {
        // 判断当前用户是否有权限
        GwjInitBusiness business = checkPermission(businessLog.getBizId());
        // 修改业务当前办理人员
        business.setCurrentOperId(businessLog.getUserId());
        business.setCurrentOperName(businessLog.getRealName());
        this.updateById(business);
        // 记录日志
        logService.addSendLog(businessLog, business);
    }

    /**
     * 签署意见
     *
     * @param businessLog 意见请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signOpinion(GwjInitBusinessLog businessLog) {
        // 判断当前用户是否有权限
        GwjInitBusiness business = checkPermission(businessLog.getBizId());
        // 记录日志
        businessLog.setStepId(business.getStepId());
        logService.addSignOpinionLog(businessLog);
    }

    /**
     * 回退
     *
     * @param businessLog 意见请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void fallback(GwjInitBusinessLog businessLog) {
        // 判断当前用户是否有权限
        GwjInitBusiness business = checkPermission(businessLog.getBizId());
        // 查找上一个步骤办理人员
        GwjConfStep step = remoteGwjConfigService
            .selectPreviousGwjConfStepByFlagId(business.getBizFlagId(), business.getStepId(), SecurityConstants.INNER)
            .getData();
        if (StringUtils.isNull(step)) {
            throw new ServiceException("当前业务步骤是第一步，不能再回退");
        }
        // 设置日志的当前步骤
        businessLog.setStepId(business.getStepId());
        // 设置业务回退的步骤
        business.setStepId(step.getStepId());
        // 修改业务当前办理人员为上一个流程的最终提交人
        GwjUserDTO user = logService.getPreviousSubmitUser(business.getBizId(), step.getStepId());
        business.setCurrentOperId(user.getUserId());
        business.setCurrentOperName(user.getRealName());
        // 设置回退状态
        business.setStatus(GwjBusinessStatus.FALLBACK.getCode());
        this.updateById(business);
        // 保存回退日志
        businessLog.setRealName(user.getRealName());
        businessLog.setUserId(user.getUserId());
        logService.addFallbackLog(businessLog);
    }

    /**
     * 验证当前用户是否有操作权限
     *
     * @param bizId 业务ID
     * @return /
     */
    @Override
    public GwjInitBusiness checkPermission(Long bizId) {
        Long currentUserId = SecurityUtils.getUserId();
        GwjInitBusiness business = this.getById(bizId);
        if (StringUtils.isNull(business)) {
            throw new ServiceException("查无相关业务");
        }
        if (!currentUserId.equals(business.getCurrentOperId())) {
            throw new ServiceException("当前办事员没有权限操作本业务");
        }
        return business;
    }

    /**
     * 案例信息
     *
     * @param bizId 业务ID
     * @return /
     */
    @Override
    public GwjInitBusiness caseInfo(Long bizId) {
        return this.getById(bizId);
    }

    /**
     * 获取拉取过的楼栋
     *
     * @param areaId 地区ID
     * @param projectCode 项目标识码
     * @return /
     */
    @Override
    public List<Map<String, Object>> getExistBuild(Long areaId, String projectCode) {
        GwjInitBusinessBuild businessBuild = new GwjInitBusinessBuild();
        businessBuild.setAreaId(areaId);
        businessBuild.setProjectCode(projectCode);
        List<GwjInitBusinessBuild> builds = businessBuildService.getList(businessBuild);
        List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
        if (StringUtils.isNotEmpty(builds)) {
            // 去重
            List<String> codes =
                builds.stream().distinct().map(GwjBaseBusinessBuild::getBuildCode).collect(Collectors.toList());
            codes.forEach(code -> {
                Map<String, Object> map = new HashMap<String, Object>(16);
                map.put("buildCode", code);
                // 设置初始状态给前端
                map.put("status", 0);
                maps.add(map);
            });
        }
        return maps;
    }

    /**
     * 删页
     *
     * @param bizId 业务id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByBizId(Long bizId) {
        // 清空业务信息
        GwjInitBusiness business = checkPermission(bizId);
        business.setApplicantName("");
        business.setPhone("");
        business.setBizName("");
        business.setArchivesNum("");
        this.updateById(business);
        // 删除业务小区、楼栋、房屋及业主信息
        if (StringUtils.isNotEmpty(businessCommunityService.getList(bizId))) {
            businessCommunityService.deleteByBizId(bizId);
        }
        if (StringUtils.isNotEmpty(businessBuildService.getListByBizId(bizId))) {
            businessBuildService.deleteByBizId(bizId);
        }
        if (StringUtils.isNotEmpty(businessHouseService.getListByBizId(bizId))) {
            businessHouseService.deleteByBizId(bizId);
        }
        if (StringUtils.isNotEmpty(businessOwnerService.getListByBizId(bizId))) {
            businessOwnerService.deleteByBizId(bizId);
        }
        // 清空日志
        logService.deleteByBizId(bizId);
    }

    /**
     * 查询业务流程
     *
     * @param bizId 业务ID
     * @param bizFlagId 业务标识
     * @return /
     */
    @Override
    public List<GwjInitBusinessFlowDTO> getBusinessFlow(Long bizId, Integer bizFlagId) {
        List<GwjConfStep> steps =
            remoteGwjConfigService.selectGwjConfStepListByFlagId(bizFlagId, SecurityConstants.INNER).getData();
        List<GwjInitBusinessFlowDTO> flows = GwjConvertUtil.convertList(steps, GwjInitBusinessFlowDTO.class);
        if (StringUtils.isNotNull(bizId)) {
            GwjInitBusiness business = this.getById(bizId);
            try {
                flows.forEach(flow -> {
                    if (flow.getStepId().equals(business.getStepId())) {
                        flow.setCurrent(true);
                        flow.setCurrentOperator(business.getCurrentOperName());
                        throw new ServiceException("");
                    } else {
                        GwjUserDTO user = logService.getPreviousSubmitUser(bizId, flow.getStepId());
                        if (StringUtils.isNotNull(user)) {
                            flow.setCurrentOperator(user.getRealName());
                        }
                    }
                });
            } catch (Exception ignored) {}
        } else {
            flows.get(0).setCurrentOperator(SecurityUtils.getLoginUser().getSysUser().getRealName());
            flows.get(0).setCurrent(true);
        }
        return flows;
    }
}
